<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>document</title>
	<style>
		* {
			margin: 0;
			padding: 0;
		}	
		ul {
			position: relative;
			padding-left: 40px;
		}
		ul li {
			list-style: none;
		}
		ul li p {
			height: 25px;
			line-height: 25px;
			display: inline-block;
		}
		ul li .add {
			margin-left: 20px;
			cursor: pointer;
			color: lightgreen;
		}
		ul li .deletes {
			margin-left: 10px;
			cursor: pointer;
			color: #ff0000;
		}
		ul li p:hover {
			cursor: pointer;
		}
		ul li p::after {
			content: "";
			position: absolute;
			left: 10px;
			top: 0;
			width: 1px;
			height: 13px;
			background: #000;
		}
		ul li p::before {
			content: "";
			position: absolute;
			left: 10px;
			top: 13px;
			width: 25px;
			height: 1px;
			background: #000;
		}

		.tree-wrap>ul>li>p:first-child::after{
			display: none;
		}
		.tree-wrap>ul>li>p:first-child::before{
			display: none;
		}
	</style>
</head>
<body>
	<div class="tree-wrap">
		
	</div>
	<script>
		var arr = [
			{
				"name": "张三",
				"children": [
					{
						"name": "张三222",
						"children": [
							{
								"name": "张三333"
							}
						]
					}
				]
			},
			{"name": "小明"},
			{
				"name": "john",
				"children": [
					{
						"name": "john22"
					}
				]
			}
		]

		function Init() {
			document.querySelector('.tree-wrap').innerHTML = tree(arr)
		}
		Init()

		function tree(data) {
			var str = `<ul>`
			for(var i = 0; i < data.length; i++){
				str += `<li>`;
				str += `
					<p data-flag="true" onClick="checkNode(event)">${data[i].name}</p>
					<span class="add" onClick="add(event)">添加</span>
					<span class="deletes" onClick="deletes(event)">删除</span>`;
				if(data[i].children && data[i].children.length) {
					str += tree(data[i].children);
				}
				str += `</li>`;
			}

			str += `</ul>`
			return str
		}
		
		// 检查元素并展开折叠
		function checkNode(event) {
			var flag = event.target
			// 获取当前点击DOM的同级元素标签
			var oSibling = event.target.parentNode.lastChild;
			if(!!oSibling && !!oSibling.childNodes) {
				var oChild = Array.prototype.slice.call(oSibling.childNodes);
				for(var i = 0; i < oChild.length; i++){
					// 表示非文本节点
					if(oChild[i].nodeType === 1){
						if(getData(flag.getAttribute('data-flag'))) {
							flag.setAttribute("data-flag", false)
							oChild[i].style.display = 'none'
						} else {
							flag.setAttribute("data-flag", true)
							oChild[i].style.display = 'block'
						}
					}
				}
			}
		};

		// 删除
		function deletes(event) {
			// 获取到当前节点的爷爷节点
			var oGrandpa = event.target.parentNode.parentNode

			// 获取到当前节点的曾祖父节点
			var oGreatGrandfather = event.target.parentNode.parentNode.parentNode

			// 表示是祖父节点
			if(oGreatGrandfather.tagName === 'DIV') {			
				// 获取到当前节点的父节点，即（ul节点）
				var oParent = event.target.parentNode
				// 获取到爷爷节点，即（li节点）
				var oParents = oGrandpa
			} else {
				// 获取到当前节点的爷爷节点，即（ul节点）
				var oParent = oGrandpa
				// 获取到曾祖父节点，即（li节点）
				var oParents = oGreatGrandfather
			}

			// 删除掉ul节点
			oParents.removeChild(oParent)
		}

		// 添加
		function add(event) {
			var oParent = event.target.parentNode
			var oSpace = document.createElement('ul')
			oParent.appendChild(oSpace)
			oSpace.innerHTML = createNode()
		}

		// 文本
		function createNode() {
			var addStr = `
							<li>
								<p data-flag="true" onClick="checkNode(event)">sdfsdfsd</p>
								<span class="add" onClick="add(event)">添加</span>
								<span class="deletes" onClick="deletes(event)">删除</span>
							</li>
					`;
			return addStr
		}

		// JQ源码转换自定义属性
		function getData(data) {
			if ( data === "true" ) {
				return true;
			}

			if ( data === "false" ) {
				return false;
			}

			if ( data === "null" ) {
				return null;
			}
			return data;
		}
	</script>
</body>
</html>